package cn.yza.设计模式.单例模式;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicLong;

/** 饿汉式
 * @author Honglixi
 * @create 2021-10-25 10:09
 */
public class SingletonTest02 {

    public static void main(String[] args) {

        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); // true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

        // 测试
        long instance3 = Singleton.getInstance().getId();
        long instance4 = Singleton.getInstance().getId();

        System.out.println(instance3 == instance4); // true
        System.out.println("instance.hashCode=" + instance3);
        System.out.println("instance2.hashCode=" + instance4);
//        for (int i = 0; i < 2; i++) {
//            new Thread( () -> {
//                Singleton instance1 = Singleton.getInstance();
//                System.out.println(instance == instance2);
//            }).start();
//
//        }

    }
}


/**
 * 饿汉式 静态代码块
 */
class Singleton {
    private AtomicLong id = new AtomicLong(0);

    // 1. 构造器私有化
    private Singleton() {}

    // 2.本类内部创建对象实例
    private static Singleton instance;

    static { // 在静态代码块中，创建单例对象
        instance = new Singleton();
    }

    // 3. 提供一个公有的静态方法，返回实例对象
    public static Singleton getInstance() {
        return instance;
    }
    public long getId() {
        return id.incrementAndGet();
    }

    public static void main(String[] args) {
        Singleton singleton = new Singleton();
        Field[] declaredFields = singleton.getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
        }
    }

}

/**
 * 饿汉式 静态变量
 */
class Singleton2 {
    private AtomicLong id = new AtomicLong(0);

    private static final Singleton2 instance2 = new Singleton2();

    private Singleton2() {}
    public static Singleton2 getInstance() {
        return instance2;
    }
    public long getId() {
        return id.incrementAndGet();
    }
}